/**
 * J<i>ava</i> U<i>tilities</i> for S<i>tudents</i>
 */
package jus.aor.printing;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.lang.management.ManagementFactory;
import java.nio.ByteBuffer;
import java.util.Date;

/**
 * Représentation d'une identification de Job (travail d'impression),
 * l'identification de la JVM cliente et la date en millisecondes doivent
 * suffire pour être unique.
 *
 * @author Morat
 */
public class JobKey {

    /**
     * l'identification de la jvm
     */
    public String serverId;
    /**
     * la date
     */
    public long date;

    /**
     * construit un JobKey
     */
    public JobKey() {
        this(new Date().getTime());
    }

    /**
     * construit un JobKey ayant la date date fournie.
     *
     * @param date la date du job
     */
    public JobKey(long date) {
        this.serverId = ManagementFactory.getRuntimeMXBean().getName();
        this.date = date;
    }

    /**
     * Construit un JobKey à partir du tableau de bytes représentant la forme
     * textuelle du JobKey
     *
     * @param marshal le tableau de bytes de la forme textuelle
     */
    public JobKey(byte[] marshal) {

        //-----------------------------------------------------------------------------

        String chaine = "";
        this.date = ByteBuffer.wrap(marshal).getLong();

        for (int i = 8; i < marshal.length; i++) {
            chaine = chaine + (char) marshal[i];
        }
        this.serverId = chaine;

        //-----------------------------------------------------------------------------
    }

    /**
     * restitue le tableau de bytes de la forme textuelle.
     *
     * @return le tableau de bytes de la forme textuelle
     */
    public byte[] marshal() {
        //0             8                                   8+taille 
        //-------------------------------------------------------------------
        //|    date     |       nom serveur: un char par byte               |
        //-------------------------------------------------------------------
        byte[] marsh;
        //long vers bytes
        byte[] temp = ByteBuffer.allocate(8).putLong(this.date).array();
        // string vers bytes
        byte[] nameServer = this.serverId.getBytes();

        // tableau a renvoyer, taille de la chaine de caractere + 8 (un long)
        marsh = new byte[nameServer.length + 8];
        int separation = 8; // on commence a 8eme bit.
        //ajout de date a marsh
        for (int i = 0; i < separation; i++) {
            marsh[i] = temp[i];
        }
        //ajout de nom a marsh
        for (int i = separation; i < marsh.length && i - separation < nameServer.length; i++) {
            marsh[i] = nameServer[i - separation];
        }


        return marsh;
        //-----------------------------------------------------------------------------
    }

    /**
     * la forme textuelle : "<<b>serverId</b>>¤<<b>date</b>>" où <<b>X</b>> est
     * la repésentation textuelle de l'attribut correspondant
     */
    public String toString() {
        return (serverId + "¤" + date);
    }

    /**
     * L'équivalence de 2 JobKey, si jobId est vide il n'est pas pris en compte,
     * si date est 0 elle n'est pas prise en compte.
     *
     * @param other l'autre opérande
     * @return vrai si l'équivalence est vérifiée, faux sinon.
     */
    public boolean equals(Object other) {
        if (!(other instanceof JobKey)) {
            return false;
        }
        JobKey o = (JobKey) other;
        if (!serverId.equals(o.serverId)) {
            return false;
        }
        if (o.date == 0) {
            return true;
        }
        return date == o.date;
    }
}
